export default {
  normal: `@Post('/normal')
async dangerousLogin(@Body() { username, password }: LoginType) {
  checkEssentialParams(username, password);
  const target = await this.userService.findUser(username, null, () => {
    throw new UserNotFound();
  });
  if (md5(password) !== target.password) {
    return { error: 'Unauthorized' };
  }
  return {
    token: await this.userService.generateToken(username),
    username: target.username,
    avatar: target.avatar,
    background: target.background,
  };
}`,
  delay: `@Post('/delay')
async delayLogin(@Body() { username, password }: LoginType) {
  await () => {
    checkEssentialParams(username, password);
    const target = await this.userService.findUser(username, null, () => {
      throw new UserNotFound();
    });
    if (md5(password) !== target.password) {
      return { error: 'Unauthorized' };
    }
    return {
      token: await this.userService.generateToken(username),
      username: target.username,
      avatar: target.avatar,
      background: target.background,
    };
  }();
  await setTimeout(() => {}, 2000); // 延迟两秒
}`,
  limit: `@Post('/login', { middleware: [AntiBurstMiddleware] })
async login(@Body() { username, password }: LoginType) {
  checkEssentialParams(username, password);
  const target = await this.userService.findUser(
    username,
    t => {
      this.userService.changeUser(t, { updateTime: new Date() }); // 刷新用户状态
    },
    () => {
      throw new UserNotFound();
    }
  );
  if (md5(password) !== target.password) {
    return { error: 'Unauthorized' };
  }
  return {
    token: await this.userService.generateToken(username),
    username: target.username,
    avatar: target.avatar,
    background: target.background,
  };
}
// --------------------------------------------------------------------------
@Middleware()
export class AntiBurstMiddleware implements IMiddleware<Context, NextFunction> {
  resolve() {
    return async (ctx: Context, next: NextFunction) => {
      const { username } = ctx.request.body as LoginType;
      const userService = await ctx.requestContext.getAsync<UserService>(
        UserService
      );
      const target = await userService.findUser(username);
      const timeDiff = moment().diff(moment(target.updateTime), 'minute');
      // 如果超过30分钟没登陆则把尝试次数归零
      if (timeDiff > 30) {
        await userService.changeUser(target, { try_count: 0 }); // 成功登录则归零尝试次数
      }
      // 15分钟内登录三次则禁止登录
      if (target.try_count >= 3 && timeDiff < 15) {
        throw new LoginFrequently();
      }
      const result = await next();
      if (!result?.error) {
        await userService.changeUser(target, { try_count: 0 }); // 成功登录则归零尝试次数
        return result;
      } else {
        await userService.changeUser(target, {
          try_count: target.try_count + 1, // 登录失败则尝试次数+1
        });
        throw new Unauthorized();
      }
    };
  }

  static getName(): string {
    return 'anti-burst';
  }
}`,
};
